/****************************************************
	文件：TrunkThumperDomain.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/8/28 7:40:59
	功能：神树巨人  规划域（业务逻辑层）
*****************************************************/

using System;
using System.Collections.Generic;
using UnityEngine;

namespace AIFramework.HTN
{
    public class TrunkThumperDomain : DomainBase
    {
        private CompoundTask mBeTrunkThumper;
        private CompoundTask mAttackEnemy;

        private PrimitiveTask mDoTrunkSlam;
        private PrimitiveTask mNavigateToEnemy;
        private PrimitiveTask mChooseBridgeToCheck;
        private PrimitiveTask mNavigateToBridge;
        private PrimitiveTask mCheckBridge;
        private PrimitiveTask mFindTrunk;
        private PrimitiveTask mNavigateToTrunk;
        private PrimitiveTask mUprootTrunk;
        private PrimitiveTask mNavigateToLastEnemyPos;
        private PrimitiveTask mRegainLostRoar;
        private PrimitiveTask mRecoveryRoar;
        private PrimitiveTask mPickupBoulder;
        private PrimitiveTask mThrowBoulder;

        public TrunkThumperDomain(EntityBase self) : base(self) { }

        public override void Build()
        {
            base.Build();
            //基元任务：
            mDoTrunkSlam = new PrimitiveTask("DoTrunkSlam", TaskType.Primitive)
                .AddCond((ws) => ws.GetInt(E_WSProperties.WS_TrunkHealth) > 0)
                .AddBev(new DoTrunkSlamBev(mSelf))
                .AddEffects((ws) => 
                {
                    ws.Set(E_WSProperties.WS_TrunkHealth, ws.GetInt(E_WSProperties.WS_TrunkHealth) - 1);
                    ws.Set(E_WSProperties.WS_AttackedRecently, true);
                });
            mNavigateToEnemy = new PrimitiveTask("NavigateToEnemy", TaskType.Primitive)
                .AddCond((ws) => true)
                .AddBev(new MoveToBev(mSelf, (ws) => ws.Self.Brain.SetDest("陈老板")))
                .AddEffects((ws) => ws.Set(E_WSProperties.WS_Location, E_Location.EnemyLocRef));
            mChooseBridgeToCheck = new PrimitiveTask("ChooseBridgeToCheck", TaskType.Primitive)
                .AddCond((ws) => true)
                .AddBev(new ChooseBridgeToCheckBev(mSelf))
                .AddEffects((ws) => { ws.Self.Brain.SetDest("长江二桥"); });
            mNavigateToBridge = new PrimitiveTask("NavigateToBridge", TaskType.Primitive)
                .AddCond((ws) => true)
                .AddBev(new MoveToBev(mSelf, (ws) => ws.Self.Brain.SetDest("长江二桥")))
                .AddEffects((ws) => ws.Set(E_WSProperties.WS_Location, E_Location.NextBridgeLocRef));
            mCheckBridge = new PrimitiveTask("CheckBridge", TaskType.Primitive)
                .AddCond((ws) => true)
                .AddBev(new CheckBridgeBev(mSelf))
                .AddEffects((ws) => { });
            mFindTrunk = new PrimitiveTask("FindTrunk", TaskType.Primitive)
                .AddCond((ws) => true)
                .AddBev(new FindBev(mSelf))
                .AddEffects((ws) => { ws.Self.Brain.SetDest("小树林"); });
            mNavigateToTrunk = new PrimitiveTask("NavigateToTrunk", TaskType.Primitive)
                .AddCond((ws) => true)
                .AddBev(new MoveToBev(mSelf, (ws) => ws.Self.Brain.SetDest("小树林")))
                .AddEffects((ws) => ws.Set(E_WSProperties.WS_Location, E_Location.FoundTrunk));
            mUprootTrunk = new PrimitiveTask("UprootTrunk", TaskType.Primitive)
                .AddCond((ws) => true)
                .AddBev(new UprootTrunkBev(mSelf))
                .AddEffects((ws) => ws.Set(E_WSProperties.WS_TrunkHealth, 3));
            mNavigateToLastEnemyPos = new PrimitiveTask("NavigateToLastEnemyPos", TaskType.Primitive)
                .AddBev(new MoveToBev(mSelf, (ws) => ws.Self.Brain.SetDest("陈老板之前所在的位置")))
                .AddEffects((ws) => ws.Set(E_WSProperties.WS_Location, E_Location.LastEnemyPos))
                .AddExpectedEffects((ws) => ws.Set(E_WSProperties.WS_CanSeeEnemy, true));
            mRegainLostRoar = new PrimitiveTask("RegainLostRoar", TaskType.Primitive)
                .AddCond((ws) => ws.GetBool(E_WSProperties.WS_CanSeeEnemy) == true)
                .AddBev(new RegainLostRoarBev(mSelf));
            mRecoveryRoar = new PrimitiveTask("RecoveryRoar", TaskType.Primitive)
                .AddBev(new PlayAnimBev(mSelf, (ws) => ws.Self.Brain.SetAnim("恢复时的咆哮")));
            mPickupBoulder = new PrimitiveTask("PickupBoulder", TaskType.Primitive)
                .AddBev(new PickupBoulderBev(mSelf));
            mThrowBoulder = new PrimitiveTask("ThrowBoulder", TaskType.Primitive)
                .AddBev(new ThrowBoulderBev(mSelf));

            //复合任务：
            mAttackEnemy = new CompoundTask("AttackEnemy", TaskType.Compound)
                .AddMethod(
                new Method(1)
                    .AddCond((ws) => 
                    {
                        return ws.GetInt(E_WSProperties.WS_TrunkHealth) > 0
                        && ws.GetBool(E_WSProperties.WS_AttackedRecently) == false
                        && ws.GetBool(E_WSProperties.WS_CanNavigateToEnemy) == true;
                    })
                    .AddTask(mNavigateToEnemy)
                    .AddTask(mDoTrunkSlam)
                    .AddTask(mRecoveryRoar))
                .AddMethod(
                new Method(2)
                    .AddCond((ws) => ws.GetInt(E_WSProperties.WS_TrunkHealth)==0)
                    .AddTask(mFindTrunk)
                    .AddTask(mNavigateToTrunk)
                    .AddTask(mUprootTrunk)
                    .AddTask(mAttackEnemy)) //递归
                .AddMethod(
                new Method(3)
                    .AddCond((ws)=>true)
                    .AddTask(mPickupBoulder)
                    .AddTask(mThrowBoulder));

            mBeTrunkThumper = new CompoundTask("BeTrunkThumper", TaskType.Compound)
                .AddMethod(
                new Method(1)
                    .AddCond((ws) => ws.GetBool(E_WSProperties.WS_CanSeeEnemy) == true)
                    .AddTask(mAttackEnemy))
                .AddMethod(
                new Method(2)
                    .AddCond((ws) => ws.GetBool(E_WSProperties.WS_HasSeenEnemyRecently) == true)
                    .AddTask(mNavigateToLastEnemyPos)
                    .AddTask(mRegainLostRoar))
                .AddMethod(
                new Method(3)
                    .AddCond((ws) => true)
                    .AddTask(mChooseBridgeToCheck)
                    .AddTask(mNavigateToBridge)
                    .AddTask(mCheckBridge));

            //添加根节点任务：
            TaskLst.Add(mBeTrunkThumper);
        }
    }
}
